
    INCLUDE kxarm.h
    INCLUDE armmacros.s

;	EXPORT	Swap
;	EXPORT	CallFunV
;	EXPORT	CallFun

    TEXTAREA

; DWORD Swap(DWORD* pdwAddr, DWORD dwNewVal);
    LEAF_ENTRY Swap
		SWP r2, r1, [r0]
		mov r0, r2
        RETURN                  ; return to caller

;
;; use c function to implement CallFunV and CallFun
;; for asm no debug info and can't display call stack
  IF {FALSE}
; DWORD WINAPI CallFunV(DWORD dwFnAddr, DWORD dwParaDwNumb, ...);
    LEAF_ENTRY CallFunV
	   	mov		r12, sp         ; restore original sp
		stmdb	sp!, {r4-r8}	; context save
		stmdb	sp!, {r12, lr}	; context save
	
		mov		r4, r0		; dwFnAddr
		mov		r5, r1		; dwParaDwNumb
		mov		r6, r12		; stack para
		mov		r8, sp		;store sp
	
		; para1
		cmp		r5, #0
		beq		%f20
		mov		r0, r2;
	
		; para2
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
		mov		r1, r3;
	
	 	; para3
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
		ldr		r2, [r6], #4
	
	 	; para4
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
		ldr		r3, [r6]
	
		; stack paras
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
	
		; pointer to the last stack para
		add		r6, r6,  r5, LSL #2
10
		ldr		r7, [r6], #-4
		str     r7, [sp, #-4 ] !
		sub		r5, r5, #1
		cmp		r5, #0
		bne		%b10
	
; para thransfer end
20
	
		; update return address
	    mov     lr, pc
		; call function
	    bx		r4
	
funv_ret
		mov		sp,  r8		; adjust sp
		ldmia	sp!, {r12, lr}	; restore lr
		ldmia	sp!, {r4-r8}	; restore r4-r7
		RETURN                  ; return to caller


;DWORD WINAPI CallFun(DWORD dwFnAddr, DWORD dwParaDwNumb, DWORD* pdwParaS);
    LEAF_ENTRY CallFun
	   	mov		r12, sp         	; restore original sp
		stmdb	sp!, {r4-r8}	; context save
		stmdb	sp!, {r12, lr}	; context save
	
		mov		r4, r0		; dwFnAddr
		mov		r5, r1		; dwParaDwNumb
		mov		r6, r2		; pdwParaS
		mov		r7, r12		; stack para
		mov		r8, sp		; store sp

		; para1
		cmp		r5, #0
		beq		%f20
		ldr		r0, [r6], #4
	
		; para2
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
		ldr		r1, [r6], #4
	
	 	; para3
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
		ldr		r2, [r6], #4
	
	 	; para4
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
		ldr		r3, [r6]
	
		; stack paras
		sub		r5, r5, #1
		cmp		r5, #0
		beq		%f20
	
		; pointer to the last pdwParaS para
		add		r6, r6,  r5, LSL #2
10
		ldr		r7, [r6], #-4
		str     r7, [sp, #-4 ] !
		sub		r5, r5, #1
		cmp		r5, #0
		bne		%b10

; para thransfer end
20

		; update return address
	    mov     lr, pc     
		; call function
	    bx		r4
fun_ret
		mov		sp, r8		; addjst sp
		ldmia	sp!, {r12, lr}	; restore lr
		ldmia	sp!, {r4-r8}	; restore r4-r7
		RETURN                  		; return to caller

  ENDIF	;  IF {FALSE}


    END

